package io.a2a.spec;

import java.util.List;
import java.util.Map;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
import io.a2a.util.Assert;

/**
 * A public metadata file that describes an agent's capabilities, skills, endpoint URL, and
 * authentication requirements. Clients use this for discovery.
 */
@JsonInclude(JsonInclude.Include.NON_ABSENT)
@JsonIgnoreProperties(ignoreUnknown = true)
public class AgentCard {
    private static final String TEXT_MODE = "text";
    
    private String name;
    private String description;
    private String url;
    private AgentProvider provider;
    private String version;
    private String documentationUrl;
    private AgentCapabilities capabilities;
    private List<String> defaultInputModes;
    private List<String> defaultOutputModes;
    private List<AgentSkill> skills;
    private boolean supportsAuthenticatedExtendedCard;
    private Map<String, SecurityScheme> securitySchemes;
    private List<Map<String, List<String>>> security;
    private String iconUrl;
    private List<AgentInterface> additionalInterfaces;
    private String preferredTransport;
    private String protocolVersion;
    
    public AgentCard() {}
    
    public AgentCard(String name, String description, String url, AgentProvider provider,
                     String version, String documentationUrl, AgentCapabilities capabilities,
                     List<String> defaultInputModes, List<String> defaultOutputModes, List<AgentSkill> skills,
                     boolean supportsAuthenticatedExtendedCard, Map<String, SecurityScheme> securitySchemes,
                     List<Map<String, List<String>>> security, String iconUrl, List<AgentInterface> additionalInterfaces,
                     String preferredTransport, String protocolVersion) {
        Assert.checkNotNullParam("capabilities", capabilities);
        Assert.checkNotNullParam("defaultInputModes", defaultInputModes);
        Assert.checkNotNullParam("defaultOutputModes", defaultOutputModes);
        Assert.checkNotNullParam("description", description);
        Assert.checkNotNullParam("name", name);
        Assert.checkNotNullParam("skills", skills);
        Assert.checkNotNullParam("url", url);
        Assert.checkNotNullParam("version", version);
        Assert.checkNotNullParam("protocolVersion", protocolVersion);
        
        this.name = name;
        this.description = description;
        this.url = url;
        this.provider = provider;
        this.version = version;
        this.documentationUrl = documentationUrl;
        this.capabilities = capabilities;
        this.defaultInputModes = defaultInputModes;
        this.defaultOutputModes = defaultOutputModes;
        this.skills = skills;
        this.supportsAuthenticatedExtendedCard = supportsAuthenticatedExtendedCard;
        this.securitySchemes = securitySchemes;
        this.security = security;
        this.iconUrl = iconUrl;
        this.additionalInterfaces = additionalInterfaces;
        this.preferredTransport = preferredTransport;
        this.protocolVersion = protocolVersion;
    }
    
    // Getters and setters
    public String getName() { return name; }
    public void setName(String name) { this.name = name; }
    
    public String getDescription() { return description; }
    public void setDescription(String description) { this.description = description; }
    
    public String getUrl() { return url; }
    public void setUrl(String url) { this.url = url; }
    
    public AgentProvider getProvider() { return provider; }
    public void setProvider(AgentProvider provider) { this.provider = provider; }
    
    public String getVersion() { return version; }
    public void setVersion(String version) { this.version = version; }
    
    public String getDocumentationUrl() { return documentationUrl; }
    public void setDocumentationUrl(String documentationUrl) { this.documentationUrl = documentationUrl; }
    
    public AgentCapabilities getCapabilities() { return capabilities; }
    public void setCapabilities(AgentCapabilities capabilities) { this.capabilities = capabilities; }
    
    public List<String> getDefaultInputModes() { return defaultInputModes; }
    public void setDefaultInputModes(List<String> defaultInputModes) { this.defaultInputModes = defaultInputModes; }
    
    public List<String> getDefaultOutputModes() { return defaultOutputModes; }
    public void setDefaultOutputModes(List<String> defaultOutputModes) { this.defaultOutputModes = defaultOutputModes; }
    
    public List<AgentSkill> getSkills() { return skills; }
    public void setSkills(List<AgentSkill> skills) { this.skills = skills; }
    
    public boolean isSupportsAuthenticatedExtendedCard() { return supportsAuthenticatedExtendedCard; }
    public void setSupportsAuthenticatedExtendedCard(boolean supportsAuthenticatedExtendedCard) { this.supportsAuthenticatedExtendedCard = supportsAuthenticatedExtendedCard; }
    
    public Map<String, SecurityScheme> getSecuritySchemes() { return securitySchemes; }
    public void setSecuritySchemes(Map<String, SecurityScheme> securitySchemes) { this.securitySchemes = securitySchemes; }
    
    public List<Map<String, List<String>>> getSecurity() { return security; }
    public void setSecurity(List<Map<String, List<String>>> security) { this.security = security; }
    
    public String getIconUrl() { return iconUrl; }
    public void setIconUrl(String iconUrl) { this.iconUrl = iconUrl; }
    
    public List<AgentInterface> getAdditionalInterfaces() { return additionalInterfaces; }
    public void setAdditionalInterfaces(List<AgentInterface> additionalInterfaces) { this.additionalInterfaces = additionalInterfaces; }
    
    public String getPreferredTransport() { return preferredTransport; }
    public void setPreferredTransport(String preferredTransport) { this.preferredTransport = preferredTransport; }
    
    public String getProtocolVersion() { return protocolVersion; }
    public void setProtocolVersion(String protocolVersion) { this.protocolVersion = protocolVersion; }

    public static class Builder {
        private String name;
        private String description;
        private String url;
        private AgentProvider provider;
        private String version;
        private String documentationUrl;
        private AgentCapabilities capabilities;
        private List<String> defaultInputModes;
        private List<String> defaultOutputModes;
        private List<AgentSkill> skills;
        private boolean supportsAuthenticatedExtendedCard = false;
        private Map<String, SecurityScheme> securitySchemes;
        private List<Map<String, List<String>>> security;
        private String iconUrl;
        private List<AgentInterface> additionalInterfaces;
        String preferredTransport;
        String protocolVersion;

        public Builder name(String name) {
            this.name = name;
            return this;
        }

        public Builder description(String description) {
            this.description = description;
            return this;
        }

        public Builder url(String url) {
            this.url = url;
            return this;
        }

        public Builder provider(AgentProvider provider) {
            this.provider = provider;
            return this;
        }

        public Builder version(String version) {
            this.version = version;
            return this;
        }

        public Builder documentationUrl(String documentationUrl) {
            this.documentationUrl = documentationUrl;
            return this;
        }

        public Builder capabilities(AgentCapabilities capabilities) {
            this.capabilities = capabilities;
            return this;
        }

        public Builder defaultInputModes(List<String> defaultInputModes) {
            this.defaultInputModes = defaultInputModes;
            return this;
        }

        public Builder defaultOutputModes(List<String> defaultOutputModes) {
            this.defaultOutputModes = defaultOutputModes;
            return this;
        }

        public Builder skills(List<AgentSkill> skills) {
            this.skills = skills;
            return this;
        }

        public Builder supportsAuthenticatedExtendedCard(boolean supportsAuthenticatedExtendedCard) {
            this.supportsAuthenticatedExtendedCard = supportsAuthenticatedExtendedCard;
            return this;
        }

        public Builder securitySchemes(Map<String, SecurityScheme> securitySchemes) {
            this.securitySchemes = securitySchemes;
            return this;
        }

        public Builder security(List<Map<String, List<String>>> security) {
            this.security = security;
            return this;
        }

        public Builder iconUrl(String iconUrl) {
            this.iconUrl = iconUrl;
            return this;
        }

        public Builder additionalInterfaces(List<AgentInterface> additionalInterfaces) {
            this.additionalInterfaces = additionalInterfaces;
            return this;
        }

        public Builder preferredTransport(String preferredTransport) {
            this.preferredTransport = preferredTransport;
            return this;
        }

        public Builder protocolVersion(String protocolVersion) {
            this.protocolVersion = protocolVersion;
            return this;
        }

        public AgentCard build() {
            return new AgentCard(name, description, url, provider, version, documentationUrl,
                    capabilities, defaultInputModes, defaultOutputModes, skills,
                    supportsAuthenticatedExtendedCard, securitySchemes, security, iconUrl,
                    additionalInterfaces, preferredTransport, protocolVersion);
        }
    }
}